#pragma once
#include <map>
#include "AbstractHTTPServer.h"
#include "AbstractIRequest.h"
#include "AbstractIResonser.h"
#include "AbstractConf.h"
#include "Lock.h"
#include "IOCPNetwork.h"
#include "HTTPServerStatus.h"
#include "HighResolutionTimer.h"
#define MAX_IP_LENGTH 50

/*web服务*/
class HTTPServer :
	public AbstractHTTPServer
{
public:
	HTTPServer();
	~HTTPServer();

	/*
	* 回调函数接口
	*/
	 int onRequestDataReceived(AbstractIRequest* request, size_t bytesTransfered);
	 int onResponderDataSent(AbstractIResonser *responder, size_t bytesTransfered);
	 void onRequest(AbstractIRequest* request, int status);
	 void onResponder(AbstractIResonser *responder, int status);

	/*
	* 获取SERVER信息
	*/
	 //映射服务器文件路径
	 bool mapServerFilePath(const std::string& url, std::string& serverPath);
	 std::string tmpFileName();
	 const std::string& docRoot();
	 bool isDirectoryVisible();
	 const std::string& defaultFileNames();
	 const std::string& ip();
	 unsigned int port();
	 unsigned int maxConnectionsPerIp();
	 unsigned int maxConnections();
	 unsigned int maxConnectionSpeed();
	 unsigned long sessionTimeout();
	 unsigned long recvTimeout();
	 unsigned long sendTimeout();
	 unsigned long keepAliveTimeout();

	 bool run(AbstractConf * httpConfig);

	 //初始化侦听套接字
	 SOCKET initializeSocket(std::string & ipAddress, unsigned int port);

	 // 执行一次握手
	 int doAccept();

private:
	int portNumber;

	int maxConnectionNumber;

	//最大连接速度数
	unsigned maxConnectionSpeedNumber;

	//最大通过IP连接数
	unsigned int maxConnectionsPerIpNumber;

	std::string ipAddress;

	//临时文件根目录
	std::string tempFileNameAddress;

	std::string docmentRoot;

	bool isOpenDirectoryVisible;

	std::string defaultFileNamesList;

	unsigned long sessionTimeOutNumber;

	unsigned long recvTimeoutNumber;

	unsigned long sendTimeoutNumber;

	unsigned long  keepAliveTimeoutNumber;


	/* 临时文件名的前缀(用来**尽可能**避免多个HTTPServer共享同一个临时目录时的命名冲突即使系统本身可以做到) */
	char tmpFileNamePrefix[5];

	/* 临时文件名序号 */
	int tmpFileNameNo;

	/*Windows同步加锁*/
	Lock lockObj;

	// 监听完成端口
	void * listenStock;

	SOCKET socketNew;

	//是否已经运行
	bool isRun;

protected:
	
	//侦听套接字事件
	typedef struct
	{
		unsigned char * buf;

		unsigned int length;

	} AcceptSocketEvent;

	//连接定义
	typedef struct
	{
		//客户端套接字
		void * clentSocket;

		//客户端IP
		char clientIp[50];

		//开始连接时间
		unsigned __int64 startTime;

		//客户端请求套接字
		AbstractIRequest * requestClient;

		//客户端相应套接字
		AbstractIResonser *responserClient;

		//客户端端口
		unsigned int port;

	} ConnectDefinition;

	//定义连接map 对象
	typedef std::map<void *, ConnectDefinition *> ConnectMap;


	AcceptSocketEvent acceptEvent;

	IOCPNetwork iocNetWork;

	HighResolutionTimer hrt;

	// 客户端信息map
	ConnectMap clientMap;

	// 保存每个IP记录 看下ip连接数
	std::map<std::string, unsigned int> connectionIp;

	// 初始化客户端连接
	ConnectDefinition * allocConnectionByCient(char* ip, unsigned int port);

	/*
	* IOCPCallback 接收到网络事件后根据操作类型,派发到具体处理网络事件的函数.
	*/
	static void __stdcall IOCPCallback(void* s, int flags, bool result, int transfered, byte* buf, size_t len, void* param);

	void onAccept(bool success);

	/*关闭连接 可能是成功的时候关闭，也可能是失败的时候关闭*/
	void doConnectionClosed(ConnectDefinition *conn, int code);

	/*释放链接上下文对象*/
	void freeConnectionContext(ConnectDefinition *);

	// 请求完毕
	void doRequestComplete(ConnectDefinition * conn, size_t status);
};

